// Kony


#include "Checkpoint/Checkpoint.h"

#include "Components/SphereComponent.h"
#include "Game/Base_GameModeBase.h"
#include "Interaction/PlayerInterface.h"
#include "Kismet/GameplayStatics.h"

//检查点 构造体
ACheckpoint::ACheckpoint(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
	//停止tick
	PrimaryActorTick.bCanEverTick = false;

	//创建检查点网格体
	CheckpointMesh = CreateDefaultSubobject<UStaticMeshComponent>("CheckpointMesh");
	CheckpointMesh->SetupAttachment(GetRootComponent());
	CheckpointMesh->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
	//碰撞阻止所有
	CheckpointMesh->SetCollisionResponseToAllChannels(ECR_Block);

	//初始化高亮设置
	CheckpointMesh->SetCustomDepthStencilValue(CUSTOM_DEPTH_TAN);
	CheckpointMesh->MarkRenderStateDirty();//立即更新自定义深度设置

	//创建碰撞体
	Sphere = CreateDefaultSubobject<USphereComponent>("Sphere");

	// Sphere->SetupAttachment(GetRootComponent());
	Sphere->SetupAttachment(CheckpointMesh);//碰撞体 附着在网格上
	Sphere->SetCollisionEnabled(ECollisionEnabled::QueryOnly);
	//碰撞忽略所有通道
	Sphere->SetCollisionResponseToAllChannels(ECR_Ignore);
	Sphere->SetCollisionResponseToChannel(ECC_Pawn, ECR_Overlap);

	//创建移动到指定位置组件
	MoveToLocation = CreateDefaultSubobject<USceneComponent>("MoveToLocation");
	MoveToLocation->SetupAttachment(GetRootComponent());
}
//处理高光效果
void ACheckpoint::HandleGlowEffects()
{
	//设置碰撞为无
	Sphere->SetCollisionEnabled(ECollisionEnabled::NoCollision);
	//创建动态材质实例 - 从网格体获取第一个材质实例
	UMaterialInstanceDynamic* DynamicMaterialInstance = UMaterialInstanceDynamic::Create(CheckpointMesh->GetMaterial(0),this);
	//设置动态材质实例到网格体
	CheckpointMesh->SetMaterial(0, DynamicMaterialInstance);
	//调用检查点网格体动态材质实例的函数
	CheckpointReached(DynamicMaterialInstance);
}
//从存档中加载 Actor 状态
void ACheckpoint::LoadActor_Implementation()
{
	//判断是否发光
	if (bReached)
	{
		HandleGlowEffects();//处理高光效果
	}
}

void ACheckpoint::BeginPlay()
{
	Super::BeginPlay();
	//判断是否启用了碰撞回调
	if (bBindOverlapCallback)
	{
		//把球体绑定到球体碰撞重叠事件
		Sphere->OnComponentBeginOverlap.AddDynamic(this, &ACheckpoint::OnSphereOverlap);
	}
}
//显示高亮
void ACheckpoint::HighlightActor_Implementation()
{
	//判断未被点亮过的检查点 才可被选中高亮，已经点亮的检查点就不用再高亮了
	if (!bReached)
	{
		CheckpointMesh->SetRenderCustomDepth(true);
	}
}
//解除高亮
void ACheckpoint::UnHighlightActor_Implementation()
{
	CheckpointMesh->SetRenderCustomDepth(false);
}
//缓存目的地接口 用于点击这个物体时 移动到这个物体指定的位置
void ACheckpoint::SetMoveToLocation_Implementation(FVector& OutDestination)
{
	OutDestination = MoveToLocation->GetComponentLocation();
}

//处理碰撞函数
void ACheckpoint::OnSphereOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor,	UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	//检查碰撞的对象是否是玩家
	// if (OtherActor->ActorHasTag(FName("Player")))
	//检测对象是否实现了玩家接口
	if (OtherActor->Implements<UPlayerInterface>())
	{
		//设置发光变量为真 后续存档使用
		bReached = true;
		//保存游戏世界状态我放到了 Execute_SaveProgress 中
		if (ABase_GameModeBase* BaseGM = Cast<ABase_GameModeBase>(UGameplayStatics::GetGameMode(this)))
		{
			//调用保存世界动态函数
			BaseGM->SaveWorldState(GetWorld());
		}
		//保存玩家存档点
		IPlayerInterface::Execute_SaveProgress(OtherActor, PlayerStartTag);
		//如果是玩家就点亮存档点
		HandleGlowEffects();
	}
}
